package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.article.mapper.ArticleHomeMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.mess.ArticleVisitStreamMess;
import com.heima.model.wemedia.pojos.WmChannel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lzq
 * @data 2023/5/12 15:20
 */
@Service
@Slf4j
@Transactional
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private CacheService cacheService;
    @Autowired
    private ArticleHomeMapper articleHomeMapper;
    @Autowired
    private IWemediaClient iWemediaClient;
    /**
     * 热点文章计算
     */
    @Override
    public void computeHotArticle() {
        //1获取五天的文章数据
        Date dayParam = DateTime.now().minusDays(50).toDate();
        List<ApArticle> articleList = articleHomeMapper.daysArticleList(dayParam);
        //2热点文章分数的计算
        List<HotArticleVo> hotArticleVoList=articleScoreGet(articleList);
        //为每个频道缓存30篇文章
        cacheArticle(hotArticleVoList);
    }
    //为每个频道缓存30篇文章
    private void cacheArticle(List<HotArticleVo> hotArticleVoList) {

        //如果是加载推荐,直接缓存分数高的三十条数据
        SortAndCache(ArticleConstants.HOT_ARTICLE_FIRST_PAGE+ArticleConstants.DEFAULT_TAG,hotArticleVoList);

        //同步调用,获取所有频道
        ResponseResult result = iWemediaClient.getChannels();
        if(result.getCode().equals(200)){
            //数据操作需要转换 obj类型强转可能会出错   JSONArray 和json不是同一个公司的
            String jsonString = JSON.toJSONString(result.getData());
            //获取频道集合
            List<WmChannel> wmChannels = JSONArray.parseArray(jsonString, WmChannel.class);
            if (wmChannels!=null&&wmChannels.size()>0){
                for (WmChannel wmChannel : wmChannels) {
                    //获取每个频道下的文章id的集合
                    List<HotArticleVo> hotArticleVos = hotArticleVoList.stream()
                            .filter(x -> x.getChannelId().equals(wmChannel.getId()))
                            .collect(Collectors.toList());
                    //保存到redis,key添加频道标志
                    SortAndCache(ArticleConstants.HOT_ARTICLE_FIRST_PAGE+wmChannel.getId(),hotArticleVos);
                }
            }
        }
    }

    //根据频道存入缓存
    private void SortAndCache(String key,List<HotArticleVo> hotArticleVoList) {
        //按照分数倒叙排列
        hotArticleVoList = hotArticleVoList.stream()
                .sorted(Comparator.comparing(HotArticleVo::getScore).reversed())
                .collect(Collectors.toList());
        //判断文章数量取前30条
        if (hotArticleVoList.size()>30){
            hotArticleVoList = hotArticleVoList.subList(0, 30);
        }
        cacheService.set(key,JSON.toJSONString(hotArticleVoList));
    }

    //热点文章分数的计算
    private List<HotArticleVo> articleScoreGet(List<ApArticle> articleList) {
        //返回集合对象
        ArrayList<HotArticleVo> hotArticleVoArrayList = new ArrayList<>();
        //参数校验
        if (articleList!=null&&articleList.size()>0){
            //遍历五天内文章
            for (ApArticle apArticle : articleList) {
                HotArticleVo hotArticleVo = new HotArticleVo();
                //属性拷贝
                BeanUtils.copyProperties(apArticle,hotArticleVo);
                //获取每一篇文章的具体分数
                Integer score=getScore(apArticle);
                hotArticleVo.setScore(score);
                hotArticleVoArrayList.add(hotArticleVo);
            }
        }
        return hotArticleVoArrayList;
    }

    //获取每一篇文章的具体分数
    private Integer getScore(ApArticle apArticle) {
        Integer score=0;
        if (apArticle!=null){
            //点赞分
            if (apArticle.getLikes()!=null){
                score+=apArticle.getLikes()* ArticleConstants.ARTICLE_LIKES;
            }
            //收藏分
            if (apArticle.getCollection()!=null){
                score+=apArticle.getCollection()* ArticleConstants.ARTICLE_COLLECTION;
            }
            //评论分
            if (apArticle.getComment()!=null){
                score+=apArticle.getComment()* ArticleConstants.ARTICLE_COMMENT;
            }
            //阅读分
            if (apArticle.getViews()!=null){
                score+=apArticle.getComment();
            }

        }
        return score;
    }

}
